#Snow Crab agent constructor. Keeps a reference to its home cell and its position in the home cells list
#No geography has been set for this object, It could be said that it shares its homecells geography bounds
setConstructorS3("ASnowCrab", function(homecell = "", lispos = "") {
	extend(RAgent(), "ASnowCrab",
		.homecell = homecell, 
		.lispos = lispos
	)
})

##ALL DATA, EXCEPT MOVEMENT, IS ARTIFICIAL AND WAS CREATED RANDOMLY IN 10 BY 10 PEICES
##TO EASILY MAP WITH THE CURRENT STRUCTURE MADE FOR TESTING. 
#Method that generates individule snowcrab based on made up abundance data and real movement data. More complex and 
#more varieties of individuls will eventually be added so the structure of this method will depend on the data available
setMethodS3("createIndividuals", "ASnowCrab", function(this) {
	
	celpos = this$.homecell$.gridloc #Get the cell position that the crab is at in order to read the abundance 
	                                 #data at this location
	
	numMale = read.table(file.path( rootdir, c("nMale")))[celpos[1], celpos[2]] #Abundance of males at this location 
	numFemale = read.table(file.path( rootdir, c("nFemale")))[celpos[1], this$.celpos[2]] #Abundance of females at this location
   
    #Create and add a random male for each male that exists at this location
	for(i in 1:numMale){
		this$addRandMale() 
	}
	 #Tell user how many male crabs were added
	 print(paste(numMale, " Male Snowcrab added."))
})

#Method that generates and add a random male to this SnowCrab objects list
setMethodS3("addRandMale", "ASnowCrab", function(this) {
	    
		boun = this$.homecell$.geography #Get the boundary that this crab must reside within
		lo <- runif(1, min(boun[,1]), max(boun[,1])) #Generte a random longnitude for this crab
		la <-runif(1, min(boun[,2]), max(boun[,2])) #Generate a random latitude for this crab
		siz = runif(1, 80, 151) #Generate a random size for this crab. Eventually from a real distribution
		#Create the male snow crab object. It is given its position in the SnowCrab objects list, its parent 
		#snowcrab object, and its size. It will eventually hve much more data than this.		
	    newscm = ASCmale(lispos = length(this$.li)+1, size = siz, parent = this)   
		#Set the geography of the snow crab as a position tht was creted above
		newscm$setgeo(matrix(c(lo, la), ncol = 2, nrow = 1))
        this$.li[[length(this$.li)+1]] = newscm #Add the snow crabto the SnowCrab objects list

})

#Snowcrab objects do command. More commands can be added as needed
setMethodS3("do", "ASnowCrab", function(this, mes, fro) {

        #If the message is plusDay the cell is telling the SnowCrab oject that a day has passed
		#And it needs to do its daily routines. This should only happen if it has not already 
		#been told that a day has passed. It checks this with this$.homecell$.updated != this$.updated 
		#if true it changes its .updated variable and can no longer be entered untill another day has passed
		if(mes == "plusDay" && this$.homecell$.updated != this$.updated){
			this$.updated = this$.updated * -1 #Update day so it can no longer be entered when it is still the same day
			#May want to tell user that the snowcrab object is updating its day, used for testing
			#print(paste("SnowCrab updating day"))
			this$.liindex = this$.liindex + 1 #Set the list index to the start of the crab list
			while(!is.null(this$.li[this$.liindex][[1]])){ #for eAch crab in the list
				this$send("plusDay", this$.li[[this$.liindex]]) #send a command to the crab that a day has passed
				this$.liindex = this$.liindex + 1 #Move to the net crab in the list
			}
			this$.liindex = 0 #Set the crab list index back to zero so that the next dy it will start back at the first crab
		}
		#If the message is remthisSCmale, then some crab is requesting that it be removed from this SnowCrab objects list
		#The curret need for this to happen is when a crab moves from on cell into another. It must add itself to the other
		#cell and remove itself from the cell it previously resided in
		if(mes == "remthisSCmale"){
		    #Tell user what cell the crab is being removed from, usefull for testing
			print(paste("Removing SCmale fromcell:", this$.homecell$.gridloc[1], ", ", this$.homecell$.gridloc[2]))
			this$.li[length(this$.li)]$.lispos = fro$.lispos #Update the last agents lispo
			this$.li[fro$.lispos] = this$.li[length(this$.li)] #Replace with last agent in list
			this$.li[length(this$.li)] = NULL #Remove the last agent
			if(this$.liindex != 0) this$.liindex = this$.liindex - 1 #Set the agent index back one so that the last agent (now current agent) can be updated this round 
		}
		#If the message is addthisSCmale, then some crab is requesting that it be added to this SnowCrab objects list
		#The curret need for this to happen is when a crab moves from on cell into another. It must add itself to the other
		#cell and remove itself from the cell it previously resided in
		if(mes == "addthisSCmale"){
			fro$.parent = this #Upadte this crabs parent to this SnowCrab object
			fro$.lispos = length(this$.li) + 1 #Tell the crab its location in its parents list 
			this$.li[[length(this$.li)+1]] = fro #Add the crab to the end of this list
			#Tell user what cell the crab has been added to, usefull for testing
			print(paste("Adding SCmale to cell:", this$.homecell$.gridloc[1], ", ", this$.homecell$.gridloc[2]))
		}
})
